package me.sealer.ssm.service.impl;

import me.sealer.ssm.constant.ErrorCodeConstant;
import me.sealer.ssm.exception.SsmException;
import me.sealer.ssm.mapper.MenuMapper;
import me.sealer.ssm.mapper.RoleMapper;
import me.sealer.ssm.mapper.RoleMenuMapper;
import me.sealer.ssm.model.Menu;
import me.sealer.ssm.model.MenuExample;
import me.sealer.ssm.model.Role;
import me.sealer.ssm.model.RoleExample;
import me.sealer.ssm.model.RoleMenu;
import me.sealer.ssm.model.RoleMenuExample;
import me.sealer.ssm.service.RoleMenuService;
import me.sealer.ssm.service.RoleService;
import org.apache.shiro.util.Assert;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 功能描述： $ RoleMenuServiceImpl
 *
 * @author sealer
 * @email 1178884049@qq.com
 * @date 2019年12月31日 16时51分52秒
 */
@Service
public class RoleMenuServiceImpl implements RoleMenuService {
    private final RoleMenuMapper roleMenuMapper;
    private final MenuMapper menuMapper;
    private final RoleMapper roleMapper;
    private final RoleService roleService;

    public RoleMenuServiceImpl(RoleMenuMapper roleMenuMapper, MenuMapper menuMapper, RoleMapper roleMapper, RoleService roleService) {
        this.roleMenuMapper = roleMenuMapper;
        this.menuMapper = menuMapper;
        this.roleMapper = roleMapper;
        this.roleService = roleService;
    }

    @Override
    public List<Menu> queryMenusByRoleName(String roleName) {
        RoleExample roleExample = new RoleExample();
        roleExample.createCriteria().andNameEqualTo(roleName);
        List<Role> roles = roleMapper.selectByExample(roleExample);

        if (roles.size() == 0) {
            throw new SsmException(ErrorCodeConstant.ROLE_ROLE_NOT_EXISTS, new Object[]{roleName});
        }

        Assert.isTrue(roles.size() == 1, "脏数据异常");

        Role role = roles.get(0);

        // roleId --> roleMenus
        RoleMenuExample roleMenuExample = new RoleMenuExample();
        roleMenuExample.createCriteria().andRoleIdEqualTo(role.getId());
        List<RoleMenu> roleMenus = roleMenuMapper.selectByExample(roleMenuExample);

        if (CollectionUtils.isEmpty(roleMenus)) {
            return new ArrayList<>();
        }

        MenuExample menuExample = new MenuExample();
        menuExample.createCriteria().andIdIn(roleMenus.stream().map(RoleMenu::getMenuId).collect(Collectors.toList()));
        return menuMapper.selectByExample(menuExample);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void modifyRoleMenus(String roleName, List<Integer> menus) {
        Role role = roleService.queryRoleByRoleName(roleName);
        if (role == null) {
            throw new SsmException(ErrorCodeConstant.ROLE_ROLE_NOT_EXISTS, new Object[]{roleName});
        }
        int roleId = role.getId();

        // delete old role-menu relations
        RoleMenuExample roleMenuExample = new RoleMenuExample();
        roleMenuExample.createCriteria().andRoleIdEqualTo(roleId);
        roleMenuMapper.deleteByExample(roleMenuExample);

        // insert new role-menu relations
        menus.forEach(id -> {
            RoleMenu roleMenu = new RoleMenu(roleId, id);
            roleMenuMapper.insert(roleMenu);
        });
    }
}
